#include "user_main.h"

#include "nvs_flash.h"
#include "nvs.h"

static const char *TAG = "global";

static const char *ota_version_url = "http://norep.gitee.io/ota/ota_test/version";
static const char *ota_image_url = "http://norep.gitee.io/ota/ota_test/ota.bin";

int user_get_cb(httpd_req_t *req)
{
	httpd_resp_send(req, index_html_start, index_html_end - index_html_start);
	return 0;
}

int user_post_cb(httpd_req_t *req, char *content, int len)
{
	system_status_t *sys_sta = get_sys_sta();
	char ssid[32];
	char passwd[32];
	int ret = httpd_query_key_value(content,"ssid",ssid,sizeof(ssid));
	if(ret == ESP_OK) {
		printf("ssid = %s\n",ssid);
	}
	else {
		printf("error = %d\n",ret);
	}

	ret = httpd_query_key_value(content,"password",passwd,sizeof(passwd));
	if(ret == ESP_OK) {
		printf("password = %s\n",passwd);
	}
	else {
		printf("error = %d\n",ret);
	}

	if (strlen(ssid) && strlen(passwd)) {
		my_nvs_wifi_info_set(ssid, passwd);
	}
	httpd_resp_send(req, save_html_start, save_html_end - save_html_start);
	sys_sta->reboot_flag = 1;
	return 0;
}

int shortdown(void)
{
	ESP_LOGW(TAG, "===== SHOART DOWN =====");
	return 0;
}
	
int longdown(void)
{
	ESP_LOGW(TAG, "===== LONG DOWN =====");
	return 0;
}

void WIFI_Connect_cb(char *ip)
{
	system_status_t *sys_sta = get_sys_sta();
	sys_sta->network_sta = 1;
	ESP_LOGW(TAG, "wifi connect : %s", ip);
}

void WIFI_Disconnect_cb(void)
{
	system_status_t *sys_sta = get_sys_sta();
	sys_sta->network_sta = 0;
	ESP_LOGW(TAG, "wifi disconnect");
}

void WIFI_AP_STAConnect_cb(void)
{
	ESP_LOGW(TAG, "WIFI_AP_STAConnect_cb");

	my_http_cb_t user_cb;
	user_cb.get_cb = user_get_cb;
	user_cb.post_cb = user_post_cb;
	my_http_server_set_callback(user_cb);
	ESP_LOGW(TAG, "Starting webserver");
	my_start_webserver();

}

void WIFI_AP_STADisconnect_cb(void)
{
	ESP_LOGW(TAG, "WIFI_AP_STADisconnect_cb");
}

void Networl_init(void)
{
	my_wifi_t wifi_info = {};
	wifi_mode_t wifi_init_mode = WIFI_MODE_AP;

	if (my_nvs_wifi_info_get(&wifi_info)) {

		memset(&wifi_info, 0, sizeof(wifi_info));
		memcpy(wifi_info.ssid, DEFAULT_AP_MODE_SSID, strlen(DEFAULT_AP_MODE_SSID));

		if (strlen(DEFAULT_AP_MODE_PASSWORD) > 0) {
			memmove(wifi_info.password, DEFAULT_AP_MODE_PASSWORD, strlen(DEFAULT_AP_MODE_PASSWORD));
		}

		wifi_info.max_connection = 1;

		wifi_info.ap_staconnect_cb = WIFI_AP_STAConnect_cb;
		wifi_info.ap_stadisconnect_cb = WIFI_AP_STADisconnect_cb;

		wifi_init_mode = WIFI_MODE_AP;
	} else {
		wifi_info.connect_cb = WIFI_Connect_cb;
		wifi_info.disconnect_cb = WIFI_Disconnect_cb;

		wifi_init_mode = WIFI_MODE_STA;
	}
	my_wifi_init(&wifi_info, wifi_init_mode);
}

/* DS18B20控制IO操作函数 */
void DS18B20_out_cb(int sta)
{
	gpio_set_level(DS18B20_GPIO, sta);
}

int DS18B20_in_cb(void)
{
	return gpio_get_level(DS18B20_GPIO);
}

/* DS18B20控制IO模式配置 */
void DS18B20_OutPut_Mode_cb(void)
{
	gpio_set_direction(DS18B20_GPIO, GPIO_MODE_OUTPUT);
}

void DS18B20_InPut_Mode_cb(void)
{
	gpio_set_direction(DS18B20_GPIO, GPIO_MODE_INPUT);
}

/* DS18B20 us 级延时函数 */
void DS18B20_delay_us_cb(uint32_t us)
{
	ets_delay_us((uint16_t)us);
}

int  Init_DS18B20(void)
{
	gpio_config_t IO_config;
	IO_config.pin_bit_mask = GPIO_DS18B20_MASK;
	IO_config.mode = GPIO_MODE_OUTPUT;
	IO_config.pull_up_en = GPIO_PULLUP_ENABLE;
	IO_config.pull_down_en = GPIO_PULLDOWN_DISABLE;
	IO_config.intr_type = GPIO_INTR_DISABLE;
	gpio_config(&IO_config);

	DS18B20_init_t init_cb;
	init_cb.delay_us_cb = DS18B20_delay_us_cb;
	init_cb.in_cb = DS18B20_in_cb;
	init_cb.out_cb = DS18B20_out_cb;
	init_cb.in_mode_cb = DS18B20_InPut_Mode_cb;
	init_cb.out_mode_cb = DS18B20_OutPut_Mode_cb;
	
	return DS18B20_Init(init_cb);
}

#define GPIO_KEY 0
#define ACK_CHECK_EN 0x1		   /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0		   /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0				   /*!< I2C ack value */
#define NACK_VAL 0x1			   /*!< I2C nack value */
#define LAST_NACK_VAL 0x2		   /*!< I2C last_nack value */

void IIC_Write_Data(uint8_t dat1,uint8_t dat2,const uint8_t *data, uint16_t len)
{
	i2c_cmd_handle_t hi2c = i2c_cmd_link_create();
	i2c_master_start(hi2c);
	i2c_master_write_byte(hi2c, dat1, ACK_CHECK_EN);
	i2c_master_write_byte(hi2c, dat2, ACK_CHECK_EN);
	for(;len>0;len--){
		i2c_master_write_byte(hi2c, *data++, ACK_CHECK_EN);
	}
	i2c_master_stop(hi2c);
	i2c_master_cmd_begin(I2C_NUM_0, hi2c, 1000 / portTICK_RATE_MS);
	i2c_cmd_link_delete(hi2c);
}

float temp = 0;

static void task1(void *arg)
{
    char *showStr;
    i2c_config_t i2c_conf;
    i2c_conf.mode = I2C_MODE_MASTER;
    i2c_conf.sda_io_num = 2;
    i2c_conf.sda_pullup_en = 1;
    i2c_conf.scl_io_num = 14;
    i2c_conf.scl_pullup_en = 1;
    i2c_conf.clk_stretch_tick = 300; // 300 ticks, Clock stretch is about 210us, you can make changes according to the actual situation.

    ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, i2c_conf.mode));
    ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &i2c_conf));

    Oled_Init(0x78,IIC_Write_Data);

    showStr = malloc(30);
    OLED_ShowString(0, 0, "Free Mem", 16);
    OLED_ShowString(0, 4, "DS18B20:", 16);

    while (1)
    {
        // printf("Update Free Men\n");
        sprintf(showStr, "%d Byte", esp_get_free_heap_size());
        OLED_ShowString(0, 2, showStr, 16);
		if (temp != -99) {
        	sprintf(showStr, "%.3f C", temp);
        	OLED_ShowString(0, 6, showStr, 16);
		}
        vTaskDelay(500 / portTICK_RATE_MS);
    }
    vTaskDelete(NULL);
}

void app_main()
{
	int ret = 0;
	system_status_t *sys_sta = get_sys_sta();
	const esp_app_desc_t *app_desc = esp_ota_get_app_description();
	sys_sta->version = (char *)app_desc->version;
	ESP_LOGI(TAG, "app_version:%s", sys_sta->version); 
	
	system_init();

	printf("free_heap_size: %d KB\n", esp_get_free_heap_size() / 1024);
	printf("minimum_free_heap_size: %d KB\n", esp_get_minimum_free_heap_size() / 1024);

	set_key_shortDown_callback(200, shortdown);
	set_key_longDown_callback(2000, longdown);

	sys_sta->ota_version_path = ota_version_url;
	// sys_sta->ota_image_path = ota_image_url;
	
	// ESP_LOGI(TAG, "start connect wifi...");
	// Networl_init();
	ESP_LOGI(TAG, "Run");
	ret = Init_DS18B20();
	if (ret) {
		printf("DS18B20 init error\n");
	}

    xTaskCreate(task1, "task1", 2048, NULL, 20, NULL);
	DS18B20_Resolution_Config(DS18B20_12BIT);

	while (1)
	{
        ret = DS18B20_Read_Temperature(&temp);
        if (ret <= -1) {
            printf("DS18B20_Read_Temperature Error ret:%d\n", ret);
        } else {
            printf("DS18B20 temp: %.2f\n", temp);
        }

		vTaskDelay(5000 / portTICK_PERIOD_MS);
	}
}
